package com.yelin.taketitle

import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.ImageFormat
import android.graphics.Matrix
import android.hardware.Camera
import android.hardware.Camera.Parameters.FOCUS_MODE_AUTO
import android.media.ExifInterface
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.util.Log
import android.view.SurfaceHolder
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.gson.Gson
import com.orhanobut.logger.Logger
import com.soundcloud.android.crop.Crop
import com.youdao.ocr.question.OCRListener
import com.youdao.ocr.question.OCRParameters
import com.youdao.ocr.question.OcrErrorCode
import com.youdao.ocr.question.SearchingImageQuestion
import com.youdao.sdk.app.EncryptHelper
import kotlinx.android.synthetic.main.activity_take_photo.*
import java.io.*
import java.text.SimpleDateFormat
import java.util.*


class TakePhotoActivity : AppCompatActivity() {
    private val TAG = "TakePhotoActivity"
    var mCamera: Camera? = null
    lateinit var mParameters: Camera.Parameters
    lateinit var mSurfaceHolder: SurfaceHolder
    lateinit var tps: OCRParameters
    private var filePath: String? = null
    private var currentUrl = ""
    private val PERMISSION_REQUESTCODE = 0x0101

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (Build.VERSION.SDK_INT >= 27) {
            requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
        }
        setContentView(R.layout.activity_take_photo)
        tps =
            OCRParameters.Builder().timeout(10000).packageName("com.example.camera2demo").build()

        btn_preview.setOnClickListener {
            startPreview()
        }
        surfaceView.setOnClickListener {
            startPreview()
        }

        btn_take.setOnClickListener {
            takePhoto()
        }

        btn_crop.setOnClickListener {
            if (filePath == null || filePath?.isEmpty()!!) {
                Toast.makeText(this@TakePhotoActivity, "先拍照", Toast.LENGTH_SHORT).show()
                return@setOnClickListener
            }

            Logger.d("btn_crop filePath $filePath")
            Crop.of(
                Uri.parse("file://$filePath"),
                Uri.parse("file://" + getFileName())
            ).start(this)
            currentUrl = filePath!!
            filePath = getFileName()
        }
        btn_search.setOnClickListener {
            search()
        }
    }


    private fun search() {
        Thread {
            run {
                //            搜题
                val bitmap: Bitmap
                if (false) {
                    bitmap = ImageUtils.readBitmapFromFile(currentUrl)
                } else {
                    bitmap = ImageUtils.readBitmapFromAsset(resources, R.drawable.ocr_question)
                }
                var baos = ByteArrayOutputStream()
                var quality = 100
                bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos)
                var datas = baos.toByteArray()
                Logger.d("onPictureTaken : $datas")
                var bases64 = EncryptHelper.getBase64(datas)
                var count = bases64.length
                while (count > 0.90 * 1024 * 1024 && quality > 10) {
                    Logger.d("count : $count quality: $quality")
                    quality -= 10
                    baos = ByteArrayOutputStream()
                    bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos)
                    datas = baos.toByteArray()
                    bases64 = EncryptHelper.getBase64(datas)
                    count = bases64.length
                }
                SearchingImageQuestion.getInstance(tps)
                    .startSearching(bases64, object : OCRListener {
                        @SuppressLint("SetTextI18n")
                        override fun onError(error: OcrErrorCode) {
                            Logger.e("code: ${error.code} name:${error.name} ordinal:${error.ordinal}")
                            runOnUiThread(Runnable {
                                Toast.makeText(
                                    this@TakePhotoActivity,
                                    error.toString(),
                                    Toast.LENGTH_LONG
                                )
                                    .show()
                                tvtip.text =
                                    "搜题完毕 code: ${error.code} name:${error.name} ordinal:${error.ordinal}"
                            })
                        }

                        override fun onResult(result: String) {
                            runOnUiThread(Runnable {
                                tvtip.text = "搜题完毕 $result"
                                Logger.d("onResult : $result")
                                val resultBean = Gson().fromJson(result, ResultBean::class.java)
                                resultBean.questions
                                startActivity(
                                    Intent(
                                        this@TakePhotoActivity,
                                        SearchResultActivity::class.java
                                    ).apply {
                                        this.putExtra("ResultBean", resultBean)
                                    })
                            })
                        }
                    })
            }
        }.start()


    }


    private fun startCamera() {
        mSurfaceHolder = surfaceView.holder
        Thread(Runnable {
            //        打开前置摄像头
            try {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                        requestPermissions(
                            arrayOf(Manifest.permission.CAMERA),
                            PERMISSION_REQUESTCODE
                        )
                    }
                }
                mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT)
                runOnUiThread {
                    //                    开始预览
                    startPreview()
                }
            } catch (e: RuntimeException) {
                Log.e(TAG, "摄像头打开失败", e)

            }

        }).start()

    }

    /**
     * 拍照
     * */
    private fun takePhoto() {
        filePath = getFileName()
        if (mCamera == null) {
            startCamera()
            return
        }
        mCamera!!.takePicture(null, null, object : Camera.PictureCallback {
            override fun onPictureTaken(p0: ByteArray?, p1: Camera?) {
                var bMap: Bitmap
                try {// 获得图片
                    bMap = BitmapFactory.decodeByteArray(p0, 0, p0!!.size)

                    var bMapRotate: Bitmap
                    //坚拍
                    var matrix = Matrix()
                    matrix.reset()
                    matrix.postRotate(90f)
                    bMapRotate = Bitmap.createBitmap(
                        bMap, 0, 0, bMap.width,
                        bMap.height, matrix, true
                    )
                    bMap = bMapRotate

                    val file = File(getFileName()!!)
                    val bos = BufferedOutputStream(FileOutputStream(file))
                    bMap.compress(Bitmap.CompressFormat.JPEG, 100, bos)//将图片压缩到流中
                    bos.flush()//输出
                    bos.close()//关闭
                    filePath = file.path
                } catch (e: Exception) {
                    Logger.e("message ${e.message}")
                }

            }
        })
    }


    private fun startPreview() {
        if (mCamera == null) {
            startCamera()
            return
        }
        mCamera!!.cancelAutoFocus()
//        摄像头参数设置
        mParameters = mCamera!!.parameters
        val list = mParameters.supportedPictureSizes
        for (size in list) {
            Log.v("startPreview", "w:${size.width} h:${size.height}")
        }
//        旋转
//        mParameters!!.setRotation(180)
//        设置录音提示
//        mParameters!!.setRecordingHint(true)
//        设置帧率 每秒30帧
//        mParameters!!.previewFrameRate = 30
//        println("$TAG 获取帧率..." + mParameters!!.previewFrameRate)
//        println("$TAG 获取数据的格式1..." + mParameters!!.pictureFormat)
        val a = mParameters.pictureFormat
        mParameters.setPictureSize(1280, 720)
//         //设置获取数据的格式
        mParameters.pictureFormat = ImageFormat.JPEG

        val b = mParameters.pictureFormat
        mSurfaceHolder = surfaceView.holder
        mSurfaceHolder.addCallback(mCameraPreview)
        mCamera!!.setPreviewDisplay(mSurfaceHolder)
//        设置显示方向
        mCamera!!.setDisplayOrientation(0)

        mCamera!!.parameters = mParameters
//        开始预览
        mCamera!!.startPreview()
        //        自动对焦
        mParameters.focusMode = FOCUS_MODE_AUTO

        mCamera!!.autoFocus { p0, p1 ->
            if (p0) {
                Logger.v("onAutoFocus 对焦成功...")
            }
        }

    }

    override fun onPause() {
        super.onPause()
        releaseCameraAndPreview()
    }


    override fun onDestroy() {
        super.onDestroy()
        releaseCameraAndPreview()
        if (Build.VERSION.SDK_INT >= 27) {
            requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
        }
    }


    private fun releaseCameraAndPreview() {
        if (mCamera != null) {
            mCamera!!.setPreviewCallback(null)
            mCamera!!.stopPreview()
            mCamera!!.release()
            mCamera = null
        }
    }

    var mHolder: SurfaceHolder? = null
    private val mCameraPreview = object : SurfaceHolder.Callback {
        override fun surfaceChanged(p0: SurfaceHolder, p1: Int, p2: Int, p3: Int) {
        }


        override fun surfaceDestroyed(p0: SurfaceHolder) {
            mHolder = p0
            mHolder?.removeCallback(this)
            if (mCamera != null) {
                mCamera!!.setPreviewCallback(null)
                mCamera!!.stopPreview()
                mCamera!!.lock()
                mCamera!!.release()
            }

        }

        override fun surfaceCreated(p0: SurfaceHolder) {
        }

    }

    /**
     * 读取图片属性：旋转的角度
     * @param path 图片绝对路径
     * @return degree旋转的角度
     */
    public fun readPictureDegree(path: String): Int {
        var degree = 0
        try {
            val exifInterface = ExifInterface(path)
            when (exifInterface.getAttributeInt(
                ExifInterface.TAG_ORIENTATION,
                ExifInterface.ORIENTATION_NORMAL
            )) {
                ExifInterface.ORIENTATION_ROTATE_90 ->
                    degree = 90
                ExifInterface.ORIENTATION_ROTATE_180 ->
                    degree = 180
                ExifInterface.ORIENTATION_ROTATE_270 ->
                    degree = 270
            }
        } catch (e: IOException) {
            e.printStackTrace()
        }
        return degree
    }


    /**
     * 生成文件路径和文件名
     *
     * @return
     */
    @SuppressLint("SimpleDateFormat")
    private fun getFileName(): String? {
        val saveDir =
            Environment.getExternalStorageDirectory().toString() + "/testquestions"
        val dir = File(saveDir)
        if (!dir.exists()) {
            val isSuccess = dir.mkdirs()
            if (isSuccess) {
                Toast.makeText(
                    this@TakePhotoActivity,
                    "文件夹创建成功",
                    Toast.LENGTH_LONG
                ).show()
            } else {
                Toast.makeText(
                    this@TakePhotoActivity,
                    "文件夹创建失败",
                    Toast.LENGTH_LONG
                ).show()
            }
        }
        // 用日期作为文件名，确保唯一性
        val date = Date()
        val formatter =
            SimpleDateFormat("yyyy-MM-dd_HH-mm-ss")
        return saveDir + "/" + formatter.format(date) + ".png"
    }


    override fun onActivityResult(
        requestCode: Int,
        resultCode: Int,
        data: Intent?
    ) {
        if (requestCode == Crop.REQUEST_CROP) {
            imageView.visibility = View.VISIBLE
            handleCrop(resultCode, data)
        }
        if (requestCode == PERMISSION_REQUESTCODE) {
//            请求相机权限回调

        }
        super.onActivityResult(requestCode, resultCode, data)
    }

    private fun handleCrop(resultCode: Int, result: Intent?) {
        if (resultCode == Activity.RESULT_OK) {
            imageView.setImageURI(Crop.getOutput(result))
        } else if (resultCode == Crop.RESULT_ERROR) {
            Logger.e("${Crop.getError(result).message}")
            Toast.makeText(
                this,
                Crop.getError(result).message,
                Toast.LENGTH_SHORT
            ).show()
        }
        if (result == null) {
            filePath = currentUrl
        }
    }

}
